﻿using System;
using System.Web;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Web.Security;
using System.Web.Script.Serialization;
using System.Linq;

using MvcCms.Data;
using MvcCms.Service.Filters;
using MvcCms.Service.Code.Email;
using MvcCms.Service;
using MvcCms.Store.Web.ViewModels;
using MvcCms.Data.Entities;
using MvcCms.Service.Code.Encryption;
using MvcCms.Service.Code;

using MvcCms.Store.Service;
using MvcCms.Store.Web.Code;
using AutoMapper;
using MvcCms.Service.Cache;

namespace MvcCms.Store.Web.Controllers
{
    [RequireSsl(Redirect = true)]  
    public class ShoppingCartController : MvcCms.Service.Code.BaseClasses.CMSControllerBase
    {
        #region Constructors
        private readonly IStoreService _storeService;
        private readonly ICacheService _cacheService;
        private readonly ShoppingCart _shoppingCart;
        public ShoppingCartController(ShoppingCart shoppingCart, ICacheService cacheService, IStoreService storeService, IAccountService accountService, IZoneService zoneService, ICmsService cmsService)
            : base(cmsService, zoneService, accountService)
        {
            _storeService = storeService;
            _cacheService = cacheService;
            _shoppingCart = shoppingCart;
        }

        #endregion

        public ActionResult Index()
        {
            var portal = _cacheService.GetCurrentPortal();
            var cart = _shoppingCart.GetCart(this.HttpContext);
            var shippingRatesQuery = _storeService.ListShippingMethodRates(portal.PortalID).ToList();

            var orderTotal = cart.GetTotal();
            var shippingRates = shippingRatesQuery.Where(sr => decimal.Parse(sr.OrderTotalFrom.ToString()) <= orderTotal && decimal.Parse(sr.OrderTotalTo.ToString()) >= orderTotal).ToList();

            if (shippingRates.Count()==0)
            {
                shippingRates = shippingRatesQuery.Where(sr => sr.OrderTotalTo < 0).ToList();
            }

            shippingRates = shippingRates.OrderBy(sr => sr.ShippingMethod.Importance).ThenBy(sr => sr.Price).ToList();

            var viewModel = new ShoppingCartViewModel
            {
                ShippingRates = shippingRates,
                _Portal = portal,
                CartItems = cart.GetCartItems(),
                CartTotal = orderTotal
            };
            ViewBag.Title = "Review Your Shopping Cart";
            // Return the view
            return View(viewModel);
        }

        [HttpPost]
        public ActionResult AddToCart(int productId, int quantity)
        {
            var addedProduct = _storeService.GetProduct(productId);
            var cart = _shoppingCart.GetCart(this.HttpContext);
            for (int i = 1; i <= quantity; i++)
            {
                cart.AddToCart(addedProduct);
            }            
            return RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult AddToCartWithNotes(int productId, int priceOptionId, string orderNotes, int quantity)
        {
            var addedProduct = _storeService.GetProduct(productId);
            var priceOption = _storeService.GetPriceOption(priceOptionId);
            var cart = _shoppingCart.GetCart(this.HttpContext);
            for (int i = 1; i <= quantity; i++)
            {
                cart.AddToCart(addedProduct, priceOption, orderNotes);
            }             
            return RedirectToAction("Index");
        }

        [HttpPost]
        public ActionResult RemoveFromCart(int id)
        {
            var cart = _shoppingCart.GetCart(this.HttpContext);

            var product = _storeService.GetCart(id).Product;
            string productName = product.Title;

            int itemCount = cart.RemoveFromCart(id);
            var orderTotal = cart.GetTotal();

            var shippingRatesQuery = _storeService.ListShippingMethodRates(product.PortalID).ToList();
            var shippingRates = shippingRatesQuery.Where(sr => decimal.Parse(sr.OrderTotalFrom.ToString()) <= orderTotal && decimal.Parse(sr.OrderTotalTo.ToString()) >= orderTotal).ToList();
            if (shippingRates.Count() == 0)
            {
                shippingRates = shippingRatesQuery.Where(sr => sr.OrderTotalTo < 0).ToList();
            }
            shippingRates = shippingRates.OrderBy(sr => sr.ShippingMethod.Importance).ThenBy(sr => sr.Price).ToList();

            var ratesToReturn = new List<DTOShippingRate>();
            foreach (var rate in shippingRates)
            {
                var newRate = new DTOShippingRate
                {
                    ShippingRateID = rate.ShippingRateID                    
                };
                var rateConverted = decimal.Parse(rate.Price.ToString());
                var rateDisplay = "";
                if (rate.Price.HasValue) { rateDisplay = "$" + rateConverted.ToMoney(); } else { rateDisplay = Math.Round(rate.PercentOfTotal.GetValueOrDefault(), 2) + "%"; }
                newRate.RateDisplay = rateDisplay;
                ratesToReturn.Add(newRate);
            }

            var results = new ShoppingCartRemoveViewModel
            {
                Message = Server.HtmlEncode(productName) + " has been removed from your shopping cart.",
                CartTotal = cart.GetTotal(),
                CartCount = cart.GetCount(),
                ItemCount = itemCount,
                DeleteId = id,
                DTOShippingRates = ratesToReturn
            };

            return Json(results);
        }

        [HttpPost]
        public ActionResult ChooseShippingMethod(int id)
        {
            var shippingMethodRate = _storeService.GetShippingMethodRate(id);
            string shippingMethodName = shippingMethodRate.ShippingMethod.Title;

            var cart = _shoppingCart.GetCart(this.HttpContext);
            Session["ShippingMethodRateID"] = id;            

            var cartTotal = cart.GetTotal();
            var shippingTotal = 0m;
            if (shippingMethodRate.Price.HasValue)
            {
                shippingTotal = decimal.Parse(shippingMethodRate.Price.GetValueOrDefault().ToString());
            }
            else
            {
                shippingTotal = cartTotal * shippingMethodRate.PercentOfTotal.GetValueOrDefault();
            }

            var cartGrandTotal = cart.GetTotal() + shippingTotal;

            var results = new ShoppingCartRemoveViewModel
            {
                Message = Server.HtmlEncode(shippingMethodName) + " has been selected for your order.",
                ShippingTotal = Math.Round(shippingTotal, 2),
                CartTotal = Math.Round(cartGrandTotal, 2)
            };

            return Json(results);
        }

        [ChildActionOnly]
        public ActionResult CartSummary()
        {
            var cart = _shoppingCart.GetCart(this.HttpContext);

            ViewData["CartCount"] = cart.GetCount();

            return PartialView("CartSummary");
        }
    }
}